package com.example.hszpad;

import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.hszpad.modbus.ModbusSocketClient;
import com.example.hszpad.util.ScreenUtil;
import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.data.DataHolder;
import com.intelligt.modbus.jlibmodbus.data.ModbusHoldingRegisters;
import com.intelligt.modbus.jlibmodbus.exception.IllegalDataAddressException;
import com.intelligt.modbus.jlibmodbus.exception.IllegalDataValueException;
import com.intelligt.modbus.jlibmodbus.slave.ModbusSlave;
import com.intelligt.modbus.jlibmodbus.slave.ModbusSlaveFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class SlaveActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText et_address;
    private EditText et_port;
    private EditText et_quality;
    private Button btn_conn;
    private ListView list;

    private int port;
    private int address;
    private int quality;
    private MyAdapter myAdapter;
    ModbusHoldingRegisters hr;


//    private ModbusSocketClient modbusSocketClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_slave);
        WindowManager wm = getWindowManager();
        Display display = wm.getDefaultDisplay();
        Log.i("display", display.getWidth() + ":" + display.getHeight());
        findViewById(R.id.btn_hide).setOnClickListener(this);
        findViewById(R.id.btn_reshow).setOnClickListener(this);
        et_address = findViewById(R.id.et_address);
        et_port = findViewById(R.id.et_port);
        et_quality = findViewById(R.id.et_quality);
        btn_conn = findViewById(R.id.btn_conn);
        btn_conn.setOnClickListener(this);
        list = findViewById(R.id.list);
        myAdapter = new MyAdapter(this);
        list.setAdapter(myAdapter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_hide:
                ScreenUtil.hideBottomNav(this);
                break;
            case R.id.btn_reshow:
                ScreenUtil.showBottomNav(this);
                break;
            case R.id.btn_conn:
                //获取地址信息
                port = Integer.parseInt(et_port.getText().toString());
                address = Integer.parseInt(et_address.getText().toString());
                quality = Integer.parseInt(et_quality.getText().toString());
                hr = new ModbusHoldingRegisters(quality);
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            final ModbusSlave slave;
                            // 设置主机TCP参数
                            TcpParameters tcpParameters = new TcpParameters();

                            // 设置TCP的ip地址
                            InetAddress adress = null;
                            try {
                                adress = InetAddress.getByName("127.0.0.1");
                            } catch (UnknownHostException e) {
                                e.printStackTrace();
                            }

                            // TCP参数设置ip地址
                            // tcpParameters.setHost(InetAddress.getLocalHost());
                            tcpParameters.setHost(adress);

                            // TCP设置长连接
                            tcpParameters.setKeepAlive(true);
                            // TCP设置端口，这里设置是默认端口502
                            tcpParameters.setPort(port);
                            slave = ModbusSlaveFactory.createModbusSlaveTCP(tcpParameters);
                            Modbus.setLogLevel(Modbus.LogLevel.LEVEL_DEBUG);
                            MyOwnDataHolder dh = new MyOwnDataHolder();
                            dh.addEventListener(new ModbusEventListener() {
                                @Override
                                public void onWriteToSingleCoil(int address, boolean value) {
                                    System.out.print("onWriteToSingleCoil: address " + address + ", value " + value);
                                }

                                @Override
                                public void onWriteToMultipleCoils(int address, int quantity, boolean[] values) {
                                    System.out.print("onWriteToMultipleCoils: address " + address + ", quantity " + quantity);
                                }

                                @Override
                                public void onWriteToSingleHoldingRegister(int address, int value) {
                                    System.out.print("onWriteToSingleHoldingRegister: address " + address + ", value " + value);
                                }

                                @Override
                                public void onWriteToMultipleHoldingRegisters(int address, int quantity, int[] values) {
                                    System.out
                                            .print("onWriteToMultipleHoldingRegisters: address " + address + ", quantity " + quantity);
                                }
                            });

                            slave.setDataHolder(dh);
                            hr.set(0, 12345);
                            hr.set(1, 12345);
                            hr.set(2, 12345);
                            hr.set(3, 12345);
                            hr.set(4, 12345);
                            hr.set(5, 12345);
                            hr.set(6, 12345);
                            hr.set(7, 12345);
                            hr.set(8, 12345);
                            hr.set(9, 12345);
                            hr.set(10, 12345);
                            hr.set(11, 12345);
                            hr.set(12, 12345);
                            hr.set(13, 12345);
                            hr.set(14, 12345);
                            hr.set(15, 12345);
                            hr.set(16, 12345);
                            hr.set(17, 12345);
                            hr.set(18, 12345);
                            hr.set(19, 12345);
                            slave.getDataHolder().setHoldingRegisters(hr);
                            slave.setServerAddress(1);
                            /*
                             * using master-branch it should be #slave.open();
                             */
                            slave.listen();

                            /*
                             * since 1.2.8
                             */
                            if (slave.isListening()) {
                                Runtime.getRuntime().addShutdownHook(new Thread() {
                                    @Override
                                    public void run() {
                                        synchronized (slave) {
                                            slave.notifyAll();
                                        }
                                    }
                                });

                                synchronized (slave) {
                                    slave.wait();
                                }

                                /*
                                 * using master-branch it should be #slave.close();
                                 */
                                slave.shutdown();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
                break;
        }
    }

    public interface ModbusEventListener {
        void onWriteToSingleCoil(int address, boolean value);

        void onWriteToMultipleCoils(int address, int quantity, boolean[] values);

        void onWriteToSingleHoldingRegister(int address, int value);

        void onWriteToMultipleHoldingRegisters(int address, int quantity, int[] values);
    }

    public static class MyOwnDataHolder extends DataHolder {

        final List<ModbusEventListener> modbusEventListenerList = new ArrayList<ModbusEventListener>();

        public MyOwnDataHolder() {
            // you can place the initialization code here
            /*
             * something like that: setHoldingRegisters(new SimpleHoldingRegisters(10));
             * setCoils(new Coils(128)); ... etc.
             */
        }

        public void addEventListener(ModbusEventListener listener) {
            modbusEventListenerList.add(listener);
        }

        public boolean removeEventListener(ModbusEventListener listener) {
            return modbusEventListenerList.remove(listener);
        }

        @Override
        public void writeHoldingRegister(int offset, int value)
                throws IllegalDataAddressException, IllegalDataValueException {
            for (ModbusEventListener l : modbusEventListenerList) {
                l.onWriteToSingleHoldingRegister(offset, value);
            }
            super.writeHoldingRegister(offset, value);
        }

        @Override
        public void writeHoldingRegisterRange(int offset, int[] range)
                throws IllegalDataAddressException, IllegalDataValueException {
            for (ModbusEventListener l : modbusEventListenerList) {
                l.onWriteToMultipleHoldingRegisters(offset, range.length, range);
            }
            super.writeHoldingRegisterRange(offset, range);
        }

        @Override
        public void writeCoil(int offset, boolean value) throws IllegalDataAddressException, IllegalDataValueException {
            for (ModbusEventListener l : modbusEventListenerList) {
                l.onWriteToSingleCoil(offset, value);
            }
            super.writeCoil(offset, value);
        }

        @Override
        public void writeCoilRange(int offset, boolean[] range)
                throws IllegalDataAddressException, IllegalDataValueException {
            for (ModbusEventListener l : modbusEventListenerList) {
                l.onWriteToMultipleCoils(offset, range.length, range);
            }
            super.writeCoilRange(offset, range);
        }
    }
}
